from typing import List
from dto.strategy_info import StrategyInfoMetadata
from dto.strategy_assessment import RiskAssessment
from dto.strategy_info import StrategyInfoMetadata
from dto.strategy_stock_day import StrategyStockDay
from service.strategy.base_week_strategy import BaseWeekStrategy


class WeeklyUptrendStrategy(BaseWeekStrategy):
    """
    判断过去12周的整体趋势及最近2周的上涨趋势
    初始分数为0分，若过去12周呈下跌趋势则加5分，若最近2周整体上涨，则加1分
    上涨幅度大于5%时，每多3%上涨额外加分
    """

    def analyze(self, trade_info_list: List[StrategyStockDay]) -> RiskAssessment:
        """
        分析过去12周的整体趋势和最近2周的价格变化
        """
        node_point = 0
        description = ""

        # 确保有至少14周的数据
        if len(trade_info_list) >= 15:
            # 判断2个星期以前的12个星期内是否呈整体下跌趋势
            past_12_weeks = trade_info_list[3:15]  # 2个星期以前的12个星期数据
            if all(
                past_12_weeks[i].close < past_12_weeks[i - 1].close
                for i in range(1, len(past_12_weeks))
            ):
                node_point = 5  # 如果过去12个星期是下跌趋势，初始分数为5
                description += "The past 12 weeks show an overall downtrend. Initial score set to 5. "

            # 判断最近2个星期的整体趋势是否为上涨
            last_3_weeks = trade_info_list[:3]  # 最近2个星期数据
            if last_3_weeks[0].close < last_3_weeks[1].close:
                node_point += 3  # 最近2个星期整体上涨，得分 +3
                description += (
                    "The last 2 weeks show an uptrend. Score increased by 1. "
                )

                # 计算上涨比例，并根据上涨比例增加分数
                pct_up = (
                    (last_3_weeks[1].close - last_3_weeks[0].close)
                    / last_3_weeks[0].close
                    * 100
                )
                if pct_up > 5:
                    additional_points = (pct_up - 5) // 3  # 每多3%加1分
                    node_point += int(additional_points)
                    description += f"Uptrend percentage is {pct_up:.2f}%. Additional points: {int(additional_points)}. "

        # 返回风险评估对象
        return RiskAssessment(
            stock_code=trade_info_list[0].stock_code,
            description=description,
            config=self.strategyConfig(),
            node_point=node_point,
        )

    def strategyConfig(self) -> dict:
        """
        返回策略的配置
        """
        return StrategyInfoMetadata(
            strategy_code="WUS",
            strategy_name="Weekly Uptrend Strategy",
            strategy_group=1,  # 假设是关注型策略
            strategy_type="Trend Analysis",
            analysis_day=14,  # 12个星期+2个星期
            strategy_level=2,
        )
